package city.spring.controller.mealService;

import city.spring.domain.entity.mealService.FoodInfoEntity;
import city.spring.domain.entity.mealService.RecipesWeekEntity;
import city.spring.domain.entity.mealService.WeekMealEntity;
import city.spring.modules.ext.service.MealFoodExtService;
import city.spring.service.mealService.FoodInfoService;
import city.spring.service.mealService.RecipesWeekService;
import city.spring.service.mealService.WeekMealService;
import city.spring.utils.MyBatisUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/recipes")
public class RecipesWeekController extends ApiController {

    /**
     * <strong></strong> Service
     */
    private final RecipesWeekService recipesWeekService;
    private final WeekMealService weekMealService;
    private final FoodInfoService foodInfoService;
    private final MealFoodExtService mealFoodExtService;
    /**
     * 实体类（）可排序字段
     */
    private final List<SFunction<RecipesWeekEntity, ?>> entityOrderFields;

    public RecipesWeekController(RecipesWeekService recipesWeekService, WeekMealService weekMealService, FoodInfoService foodInfoService, MealFoodExtService mealFoodExtService) {
        this.recipesWeekService = recipesWeekService;
        this.weekMealService = weekMealService;
        this.foodInfoService = foodInfoService;
        this.mealFoodExtService = mealFoodExtService;
        this.entityOrderFields = new ArrayList<>();
        entityOrderFields.add(RecipesWeekEntity::getId);
        entityOrderFields.add(RecipesWeekEntity::getWeek);
        entityOrderFields.add(RecipesWeekEntity::getStartTime);
        entityOrderFields.add(RecipesWeekEntity::getEndTime);
        entityOrderFields.add(RecipesWeekEntity::getPrize);
    }

    /**
     * 获取全部的 <strong></strong> 列表
     */
    @GetMapping("all")
    public Object listAll(@PageableDefault(sort = {"week"}) Pageable pageable, RecipesWeekEntity entity) {
        LambdaQueryChainWrapper<RecipesWeekEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        return success(lambdaQuery.list());
    }

    /**
     * 分页获取 <strong></strong> 列表
     *
     * @param pageable 分页参数信息
     */
    @GetMapping
    public Object list(@PageableDefault(sort = {"week"}) Pageable pageable, RecipesWeekEntity entity) {
        LambdaQueryChainWrapper<RecipesWeekEntity> lambdaQuery = buildLambdaQuery(entity);
        MyBatisUtils.lambdaQueryAddOrder(lambdaQuery, pageable, entityOrderFields);
        Page<RecipesWeekEntity> page = lambdaQuery.page(MyBatisUtils.toPage(pageable, false));
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        for (RecipesWeekEntity record : page.getRecords()) {
            Date dateStartTime = Date.from(record.getWeek().atStartOfDay(ZoneId.systemDefault()).toInstant());
            calendar.setTime(dateStartTime);
            String year = (new SimpleDateFormat("yyyy")).format(Date.from(record.getWeek().atStartOfDay(ZoneId.systemDefault()).toInstant()));
            int week = calendar.get(Calendar.WEEK_OF_YEAR);
            String yearWeek = year + "第" + week + "周";
            record.setWeekString(yearWeek);
            try {
                if (record.isStatue()) {
                    record.setStatueString("已发布");
                } else {
                    record.setStatueString("未发布");
                }
            } catch (Exception ignore) {
                record.setStatueString("");
            }
        }
        return success(page);
    }

    /**
     * 获取一个 <strong></strong>
     *
     * @param id 主键ID
     */
    @GetMapping("{id}")
    public Object info(@PathVariable String id) {
        RecipesWeekEntity entity = recipesWeekService.getById(id);
        recipesWeekService.loadMealTime(entity);
        Date dateStartTime = Date.from(entity.getWeek().atStartOfDay(ZoneId.systemDefault()).toInstant());
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(dateStartTime);
        String year = (new SimpleDateFormat("yyyy")).format(dateStartTime);
        int week = calendar.get(Calendar.WEEK_OF_YEAR);
        String yearWeek = year + "第" + week + "周";
        entity.setWeekString(yearWeek);
        try {
            if (entity.isStatue()) {
                entity.setStatueString("已发布");
            } else {
                entity.setStatueString("未发布");
            }
        } catch (Exception e) {
            entity.setStatueString("");
        }
        return success(entity);
    }

    /**
     * 添加一个 <strong></strong>
     *
     * @param entity 新增的信息
     */
    @PostMapping
    public Object add(@RequestBody RecipesWeekEntity entity) {
        recipesWeekService.saveRecipesWeek(entity);
//        HttpHeaders headers = new HttpHeaders();
//        headers.add(HttpHeaders.LOCATION, entity.getId());
//        return new ResponseEntity<>(headers, HttpStatus.CREATED);
        return success(entity);
    }

    /**
     * 修改一个 <strong></strong>
     *
     * @param id     主键ID
     * @param entity 修改后的信息
     */
    @PutMapping("{id}")
    public Object update(@PathVariable String id, @RequestBody RecipesWeekEntity entity) {
        entity.setId(id);
        recipesWeekService.updateRecipesWeek(entity);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @GetMapping("/meal-votes/{id}")
    public Object infoMealVotes(@PathVariable String id) {
        RecipesWeekEntity entity = recipesWeekService.getById(id);
        entity.setId(id);
        this.recipesWeekService.loadWeekMeal(entity);
        List<WeekMealEntity> newWeekMealEntities = entity.getChildren();
        Set<String> newWeekMealIds = newWeekMealEntities.stream().map(WeekMealEntity::getId).collect(Collectors.toSet());
        ArrayListMultimap<String, String> map = mealFoodExtService.getMealTurn(newWeekMealIds);
        for (int i = 0; i < newWeekMealEntities.size(); i++) {
            String weekMealId = newWeekMealEntities.get(i).getId();
            Map<String, Map<Integer, List<FoodInfoEntity>>> votesMealTurnFood = weekMealService.loadVotesMealTurnFood(newWeekMealEntities.get(i));
            HashSet<String> strings = new HashSet<>(map.get(newWeekMealEntities.get(i).getId()));
            newWeekMealEntities.get(i).setMealTurn(new ArrayList<>(strings));
            newWeekMealEntities.get(i).setVotesMealTurnFood(votesMealTurnFood);
            Table<String, String, List<FoodInfoEntity>> table = HashBasedTable.create();
        }
        entity.setChildren(newWeekMealEntities);
        Date dateStartTime = Date.from(entity.getWeek().atStartOfDay(ZoneId.systemDefault()).toInstant());
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(dateStartTime);
        String year = (new SimpleDateFormat("yyyy")).format(dateStartTime);
        int week = calendar.get(Calendar.WEEK_OF_YEAR);
        String yearWeek = year + "年第" + week + "周";
        entity.setWeekString(yearWeek);
        return success(entity);
    }

    @GetMapping("/meal/{id}")
    public Object infoMeal(@PathVariable String id) {
        RecipesWeekEntity entity = recipesWeekService.getById(id);
        entity.setId(id);
//        List<WeekMealEntity> weekMealEntities = new LinkedList<>();
//        RecipesEntity recipesEntity = recipesService.getById(recipesId);
//        this.recipesService.loadMealTime(recipesEntity);
//        int menuLength = recipesEntity.getMealTime().size();
//        for(int i=1;i<=7;i++){
//            for(int j=1;j<=menuLength;j++){
//                WeekMealEntity weekMealEntity = new WeekMealEntity();
//                weekMealEntity.setMealDay(i);
//                weekMealEntity.setMealTime(j);
//                weekMealEntity.setWeekId(id);
//                weekMealEntities.add((i-1)*menuLength+j-1,weekMealEntity);
//            }
//        }
        this.recipesWeekService.loadWeekMeal(entity);
        List<WeekMealEntity> newWeekMealEntities = entity.getChildren();
//        for(int i=0;i<newWeekMealEntities.size();i++){
//            weekMealService.loadRecipesVotes(newWeekMealEntities.get(i));
//        }
        Set<String> newWeekMealIds = newWeekMealEntities.stream().map(WeekMealEntity::getId).collect(Collectors.toSet());
        ArrayListMultimap<String, String> map = mealFoodExtService.getMealTurn(newWeekMealIds);
        for (int i = 0; i < newWeekMealEntities.size(); i++) {
            String weekMealId = newWeekMealEntities.get(i).getId();
            List<String> mealTurn = mealFoodExtService.getMealTurn(weekMealId);
            HashSet<String> strings = new HashSet<>(map.get(newWeekMealEntities.get(i).getId()));
            newWeekMealEntities.get(i).setMealTurn(new ArrayList<>(strings));
            Table<String, String, List<FoodInfoEntity>> table = HashBasedTable.create();
            Map<String, List<FoodInfoEntity>> mealTurnFood = new HashMap<>();
            for (int j = 0; j < mealTurn.size(); j++) {
                List<FoodInfoEntity> entities = foodInfoService.getMealTurnFood(weekMealId, mealTurn.get(j));
                mealTurnFood.put(mealTurn.get(j), entities);
            }
            newWeekMealEntities.get(i).setMealTurnFood(mealTurnFood);
        }
        entity.setChildren(newWeekMealEntities);
//        try {
//            for(int i=0;i<newWeekMealEntities.size();i++){
//                int sort = (newWeekMealEntities.get(i).getMealDay()-1)*menuLength+newWeekMealEntities.get(i).getMealTime();
//                weekMealEntities.set(sort-1,newWeekMealEntities.get(i));
//            }
//        } catch (NullPointerException e){
//            entity.setChildren(weekMealEntities);
//        }
//        entity.setChildren(weekMealEntities);
        Date dateStartTime = Date.from(entity.getWeek().atStartOfDay(ZoneId.systemDefault()).toInstant());
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(dateStartTime);
        String year = (new SimpleDateFormat("yyyy")).format(dateStartTime);
        int week = calendar.get(Calendar.WEEK_OF_YEAR);
        String yearWeek = year + "年第" + week + "周";
        entity.setWeekString(yearWeek);
        return success(entity);
    }

//    @PutMapping("/meal/{id}")
//    public Object updateMeal(@PathVariable String id, @RequestBody RecipesWeekEntity entity,@PathVariable String recipesId) {
//        entity.setId(id);
//        List<WeekMealEntity> weekMealEntities = new LinkedList<>();
//        for(int i=0;i<21;i++){
//            weekMealEntities.add(i,new WeekMealEntity());
//        }
//        entity.setChildren(weekMealEntities);
//        recipesWeekService.updateRecipesWeek(entity);
//        return new ResponseEntity<>(HttpStatus.OK);
//    }

    /**
     * 删除一个 <strong></strong>
     *
     * @param id 主键ID
     */
    @DeleteMapping("{id}")
    public Object delete(@PathVariable String id) {
        recipesWeekService.deleteRecipesWeek(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 删除多个 <strong></strong>
     *
     * @param ids 主键ID列表
     */
    @DeleteMapping
    public Object deleteIds(@RequestBody List<String> ids) {
        recipesWeekService.deleteRecipesWeek(ids);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 获取一周期七天每日菜品供应情况
     */
    @GetMapping("/week-food/{id}")
    public Object getWeekFood(@PathVariable String id) {
        RecipesWeekEntity entity = recipesWeekService.getById(id);
        Map<DayOfWeek, List<FoodInfoEntity>> weekFoodAll = recipesWeekService.getWeekFoodAll(entity);
        return success(weekFoodAll);
    }

    /**
     * 构建查询条件内容
     *
     * @param entity 实体对象： <strong></strong>
     * @return lambda query chain wrapper
     */
    private LambdaQueryChainWrapper<RecipesWeekEntity> buildLambdaQuery(RecipesWeekEntity entity) {
        LambdaQueryChainWrapper<RecipesWeekEntity> lambdaQuery = recipesWeekService.lambdaQuery();
        lambdaQuery.eq(StringUtils.isNotBlank(entity.getId()), RecipesWeekEntity::getId, entity.getId());
        return lambdaQuery;
    }

}
